/**
 * GUI 图形化界面
 */

import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.util.ArrayList;
import java.util.Random;

public class ProjectGUI extends JFrame {
    private JButton showImage;

    private JTextField srcString;
    private JTextField destString;
    private JButton queryBridgeWord;
    private JLabel showBridgeWord;

    private JButton generateNewFile;

    private JTextField shortestSrcString;
    private JTextField shortestDestString;
    private JButton queryShortestPathLength;
    private JLabel shortestLength;

    private JButton randomPath;

    public ProjectGUI() {
        // 设置窗口标题
        super("结对编程实验");

        AdjacencyMatrix adjacencyMatrix = generateAdjacency();

        JPanel canvas = new JPanel();
        canvas.setPreferredSize(new Dimension(1000, 600));

        // 设置布局管理器为 BorderLayout
        canvas.setLayout(null);

        // 创建左侧面板用于显示图片
        JPanel leftPanel = new JPanel();
        leftPanel.setBounds(0, 0, 500, 600);

        // 创建图片标签，并设置默认图片
        JLabel imageLabel = new JLabel();
        ImageIcon defaultImageIcon = new ImageIcon("D:\\Desktop\\HIT\\SoftwareProject\\Lab1\\src\\Image\\default.png"); // 默认图片的路径
        imageLabel.setIcon(defaultImageIcon);

        // 将图片标签添加到左侧面板
        leftPanel.add(imageLabel);

        canvas.add(leftPanel);

        // 在右侧面板添加其他组件或内容...
        this.showImage = new JButton("展示有向图");
        this.showImage.setBounds(650, 20, 200, 50); // 设置按钮的位置和大小
        this.showImage.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ImageIcon icon = new ImageIcon("D:\\Desktop\\HIT\\SoftwareProject\\Lab1\\src\\Image\\DOT.png");
                Image image = icon.getImage().getScaledInstance(500, 560, Image.SCALE_DEFAULT);
                ImageIcon show = new ImageIcon(image);
                imageLabel.setIcon(show);
            }
        });

        this.srcString = new PlaceholderTextField("请输入桥连词前一字符串:");
        srcString.setBounds(650, 80, 200, 20);
        this.destString = new PlaceholderTextField("请输入桥连词后一字符串:");
        destString.setBounds(650, 110, 200, 20);

        this.showBridgeWord = new JLabel("桥接词是: ");
        this.showBridgeWord.setBounds(520, 140, 120, 50);

        this.queryBridgeWord = new JButton("查询桥接词");
        this.queryBridgeWord.setBounds(650, 140, 200, 50); // 设置按钮的位置和大小
        this.queryBridgeWord.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String queryRES = queryBridgeWords(srcString.getText(), destString.getText(), adjacencyMatrix);
                showBridgeWord.setText(queryRES);
            }
        });

        this.generateNewFile = new JButton("生成新的文本");
        this.generateNewFile.setBounds(650, 200, 200, 50);
        generateNewFile.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String defaultDirectory = "D:\\Desktop\\HIT\\SoftwareProject\\Lab1\\src";

                JFileChooser fileChooser = new JFileChooser();

                fileChooser.setCurrentDirectory(new File(defaultDirectory));

                // 创建一个文件过滤器，限制只能选择 .txt 文件
                FileNameExtensionFilter filter = new FileNameExtensionFilter("Text files", "txt");
                fileChooser.setFileFilter(filter);

                int result = fileChooser.showOpenDialog(null);

                if (result == JFileChooser.APPROVE_OPTION) {
                    File selectedFile = fileChooser.getSelectedFile();
                    generateNewText(selectedFile.getAbsolutePath(), adjacencyMatrix);
                }
            }
        });

        // 计算最短路径
        this.shortestSrcString = new PlaceholderTextField("请输入最短路径起始点:");
        this.shortestSrcString.setBounds(650, 260, 200, 20);
        this.shortestDestString = new PlaceholderTextField("请输入最短路径终止点:");
        this.shortestDestString.setBounds(650, 290, 200, 20);
        this.shortestLength = new JLabel("最短长度是:");
        this.shortestLength.setBounds(520, 320, 120, 50);
        this.queryShortestPathLength = new JButton("计算最短长度");
        this.queryShortestPathLength.setBounds(650, 320, 200, 50);
        this.queryShortestPathLength.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int shortestLengthInt = calcShortestPath(shortestSrcString.getText(), shortestDestString.getText(), adjacencyMatrix);
                if (shortestLengthInt == -1) {
                    shortestLength.setText("不可达");
                } else {
                    shortestLength.setText(String.valueOf(shortestLengthInt));
                }

            }
        });

        this.randomPath = new JButton("随机游走");
        this.randomPath.setBounds(650, 380, 200, 50);
        this.randomPath.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                randomWalk(adjacencyMatrix);
            }
        });

        canvas.add(this.showImage);
        canvas.add(this.srcString);
        canvas.add(this.destString);
        canvas.add(this.showBridgeWord);
        canvas.add(this.queryBridgeWord);
        canvas.add(this.generateNewFile);
        canvas.add(this.shortestSrcString);
        canvas.add(this.shortestDestString);
        canvas.add(this.shortestLength);
        canvas.add(this.queryShortestPathLength);
        canvas.add(this.randomPath);

        // 将幕布添加到窗口中
        add(canvas);

        // // 设置窗口大小和关闭操作
        setSize(1000, 600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setVisible(true);

    }

    // 查询桥接词
    private String queryBridgeWords(String word1, String word2, AdjacencyMatrix adjacencyMatrix) {
        int srcIndex = adjacencyMatrix.getIndexMatrix(word1.toLowerCase());
        int destIndex = adjacencyMatrix.getIndexMatrix(word2.toLowerCase());
        if (srcIndex == -1 || destIndex == -1) {
            return "";
        }
        for (int i = 0; i < adjacencyMatrix.getNumVertices(); i++) {
            if (adjacencyMatrix.getWeight(srcIndex, i) != 0 && adjacencyMatrix.getWeight(i, destIndex) != 0) {
                return adjacencyMatrix.getNameFromIndex(i);
            }
        }
        return "";
    }

    // 生成新的文本
    private void generateNewText(String srcFileName, AdjacencyMatrix adjacencyMatrix) {
        String newText = "";
        try (BufferedReader br = new BufferedReader(new FileReader(srcFileName))) {
            String line;
            String preWord = "";
            while ((line = br.readLine()) != null) {
                // 按照非字母字符拆分每行文本成单词数组
                String[] words = line.split("[^a-zA-Z]+");

                for (String word : words) {
                    word = word.toLowerCase();
                    if (preWord.equals("")) {
                        preWord = word;
                        newText += word;
                        continue;
                    }
                    String middleWord = queryBridgeWords(preWord, word, adjacencyMatrix);
                    System.out.println(preWord + "   " + word + "   " + middleWord);
                    if (!middleWord.equals("")) {
                        newText += " " + middleWord + " " + word;
                    } else {
                        newText += " " + word;
                    }
                    preWord = word;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        String newFileName = srcFileName.split("\\.")[0] + "-new" + "." + srcFileName.split("\\.")[1];

        try {
            // 创建文件对象
            File file = new File(newFileName);

            // 创建文件写入流
            FileWriter fw = new FileWriter(file);
            BufferedWriter bw = new BufferedWriter(fw);

            // 写入内容
            bw.write(newText);

            // 关闭流
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private AdjacencyMatrix generateAdjacency() {
        // 解析文件内容成有向图的邻接矩阵
        FileParsing fileParsing = new FileParsing();
        AdjacencyMatrix adjacencyMatrix =
                fileParsing.parsingFile("D:\\Desktop\\HIT\\SoftwareProject\\Lab1\\src\\test.txt");
        // 将邻接矩阵转成图片
        AdjacencyMatrix2DOT2Image adjacencyMatrix2DOT2Image = new AdjacencyMatrix2DOT2Image();
        adjacencyMatrix2DOT2Image.showDirectedGraph(adjacencyMatrix);
        return adjacencyMatrix;
    }

    // 最短路径
    private int calcShortestPath(String srcString, String destString, AdjacencyMatrix adjacencyMatrix) {
        if (adjacencyMatrix.getIndexMatrix(srcString) == -1 || adjacencyMatrix.getIndexMatrix(destString) == -1){
            return -1;
        }

        DijkstraTools dijkstraTools = new DijkstraTools();
        int res = dijkstraTools.dijkstraFindShortestPath(srcString, destString, adjacencyMatrix);
        return res;
    }

    // 随机游走
    private void randomWalk(AdjacencyMatrix adjacencyMatrix) {
        Random r = new Random();
        int current = r.nextInt(adjacencyMatrix.getNumVertices());
        // 从 index 开始
        String walkPath = adjacencyMatrix.getNameFromIndex(current);

        ArrayList<String> hasWalkedPath = new ArrayList<>();

        while (true) {
            int basic = r.nextInt(adjacencyMatrix.getNumVertices());
            boolean can = false;
            for (int i = 0; i < adjacencyMatrix.getNumVertices(); i++) {
                int next = (basic + i) % adjacencyMatrix.getNumVertices();
                if (adjacencyMatrix.getWeight(current, next) != 0) {
                    String pathString = current + "-" + next;
                    if (hasWalkedPath.contains(pathString)) {
                        // 重复了
                        continue;
                    }
                    can = true;
                    walkPath += (" " + adjacencyMatrix.getNameFromIndex(next));
                    hasWalkedPath.add(current + "-" + next);
                    current = next;
                    break;
                }
            }
            if (!can) {
                break;
            }
        }

        // 写入文件
        String fileName = "D:\\Desktop\\HIT\\SoftwareProject\\Lab1\\src\\walkpath.txt";
        try {
            // 创建文件对象
            File file = new File(fileName);

            // 创建文件写入流
            FileWriter fw = new FileWriter(file);
            BufferedWriter bw = new BufferedWriter(fw);

            // 写入内容
            bw.write(walkPath);

            // 关闭流
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);

        // 获取窗口的绘图对象
        Graphics2D g2d = (Graphics2D) g;

        // 设置直线的起点和终点坐标
        int x1 = 510;
        int y = 105;
        int x2 = 990;

        // 绘制直线
        g2d.drawLine(x1, y, x2, y);

        y = 225;

        g2d.drawLine(x1, y, x2, y);

        y = 285;

        g2d.drawLine(x1, y, x2, y);

        y = 405;

        g2d.drawLine(x1, y, x2, y);

    }
}
